package com.starsoft.smdc.service;

import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.starsoft.frame.core.orm.PageObject;
import com.starsoft.frame.util.DateUtil;
import com.starsoft.smdc.bean.SmdcHolidayDetail;
import com.starsoft.smdc.dao.HolidayDao;

@Service
public class HolidayService{

	@Autowired
	HolidayDao holidayDao;
	
	public void insertHoliday(Date date, boolean isHoliday){
		holidayDao.insert(date, isHoliday);
	}

	public Map<String, Object> pageQuery(PageObject po) {
		return holidayDao.pageQuery(SmdcHolidayDetail.class, po);
	}
	
	public void delete(SmdcHolidayDetail detail){
		holidayDao.delete(SmdcHolidayDetail.class, detail.getId());
	}

	public boolean isBusinessDay(Date date){
		SmdcHolidayDetail holidayDetail = holidayDao.getdefault(date);
		if(holidayDetail!=null){
			return !holidayDetail.getIsHoliday();
		}
		return !DateUtil.isWeekend(date);
	}
	
	public boolean isBusinessDay(ZonedDateTime date){
		SmdcHolidayDetail holidayDetail = holidayDao.getdefault(DateUtil.toDate(date));
		if(holidayDetail!=null){
			return !holidayDetail.getIsHoliday();
		}
		return !DateUtil.isWeekend(date);
	}
	
	public boolean isTradeTime(Date date) {
		boolean isbusy = isBusinessDay(date);
		boolean isToday = DateUtil.isToday(date);
		if (isbusy && isToday) {
			ZonedDateTime dateTime = DateUtil.toZoned(date);
			int seconds = dateTime.getHour()*3600+dateTime.getMinute()*60+dateTime.getSecond();
			double a = 9.5 * 60 * 60;
			double b = 11.5 * 60 * 60;
			double c = 13 * 60 * 60;
			double d = 15 * 60 * 60;
			if ((seconds > a && seconds < b) || (seconds > c && seconds < d)) {
				return true;
			}
		}
		return false;
	}
	
	public boolean isTradeTime(){
		return isTradeTime(new Date());
	}
	
	public boolean isBeforeOpen(Date date) {
		ZonedDateTime dateTime = DateUtil.toZoned(date);
		int seconds = dateTime.getHour() * 3600 + dateTime.getMinute() * 60 + dateTime.getSecond();
		double open = 9.5 * 60 * 60;
		if (seconds < open) {
			return true;
		}
		return false;
	}
	
	public boolean isBeforeClose(Date date) {
		ZonedDateTime dateTime = DateUtil.toZoned(date);
		int seconds = dateTime.getHour()*3600+dateTime.getMinute()*60+dateTime.getSecond();
		double close = 15 * 60 * 60;
		if (seconds < close) {
			return true;
		}
		return false;
	}
	
	public Date getBusinessDay(Date date, boolean isBack){
		if(isBusinessDay(date)){
			return date;
		} else {
			int days = isBack ? -1:1;
			return getNextBusinessDay(date, days);
		}
	}
	
	public List<Date> getBusinessDayList(Date beginDate, Date endDate, Integer filterSize) {
		List<Date> result = new ArrayList<>();
		Date date = this.getBusinessDay(beginDate, false);
		while(!date.after(endDate)){
			result.add(date);
			date =  this.getNextBusinessDay(date, 1);
		}
		if(filterSize==null) return result;
		
		List<Date> result2 = new ArrayList<>();
		int step = result.size()/filterSize;
		int index = 1;
		for(Date tmp : result) {
			if(index==1) result2.add(tmp);
			index++;
			if(index>step) index = 1;
		}
		return result2;
	}
	
	public Date getNextBusinessDay(Date date, int days){
		ZonedDateTime dateTime = DateUtil.toZoned(date);
		int step = days > 0 ? 1 : -1;
		int count=0;
		while(count<Math.abs(days)){
			dateTime = dateTime.plusDays(step);
			if(isBusinessDay(dateTime)){
				count++;
			}
		}
		return DateUtil.toDate(dateTime);
	}
	
	public Date getBusinessMonthEnd(Date date){
		ZonedDateTime dateTime = DateUtil.toZoned(date);
		ZonedDateTime lastday = dateTime.with(TemporalAdjusters.lastDayOfMonth());
		return getBusinessDay(DateUtil.toDate(lastday), true);
	}
}
